//
//  VC12GCD.swift
//  ChapterAll
//
//  Created by Kevin on 2020/5/7.
//  Copyright © 2020 Kevin. All rights reserved.
//

import UIKit

class VC12GCD: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        test20()
    }
    
    func test20() -> Void {
        print("test20 start")
        
        var count = 20
        
        let timer = DispatchSource.makeTimerSource(flags: .strict, queue: .global())
        timer.schedule(deadline: .now(), repeating: .seconds(1))
        timer.setEventHandler {
            count -= 1
            if count <= 0 {
                timer.cancel()
            }
            DispatchQueue.main.async {
                print("\(count) main thread update ui \(Thread.current)")
            }
        }
        timer.resume()
        
        DispatchQueue.concurrentPerform(iterations: 5) { (i) in
            print("\(i),\(Thread.current)")
        }
        print("test20 finish")
    }
    
    func test19() -> Void {
        print("test19 start")
        DispatchQueue.concurrentPerform(iterations: 5) { (i) in
            print("\(i),\(Thread.current)")
        }
        print("test19 finish")
    }
    
    func test18() -> Void {
        print("test18 start")
        let semaphore = DispatchSemaphore(value: 2)
        let queue = DispatchQueue.global()
        queue.async {
            semaphore.wait()
            print("run start 1")
            sleep(2)
            print("run finish 1")
            semaphore.signal()
        }
        queue.async {
            semaphore.wait()
            print("run start 2")
            sleep(2)
            print("run finish 2")
            semaphore.signal()
        }
        queue.async {
            semaphore.wait()
            print("run start 3")
            sleep(2)
            print("run finish 3")
            semaphore.signal()
        }
        print("test18 finish")
    }
    
    func test17() -> Void {
        print("test17 start")
        
        let group = DispatchGroup()
        let queue = DispatchQueue.global()
        
        group.enter()
        queue.async(group: group, qos: .default, flags: []) {
            DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
                for i in 0...5 {
                    print("下载A=\(Thread.current),i=\(i)")
                }
                group.leave()
            }
        }
        
        group.enter()
        queue.async(group: group, qos: .default, flags: []) {
            for i in 0...5 {
                print("下载B=\(Thread.current),i=\(i)")
            }
            group.leave()
        }
        
        group.notify(queue: queue) {
            print("回到该队列中执行=\(Thread.current)")
        }
        print("test17 finish")
    }
    
    func test16() -> Void {
        print("test16 start")
        
        let group = DispatchGroup()
        let queue = DispatchQueue.global()
        
        queue.async(group: group, qos: .default, flags: []) {
            DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
                for i in 0...5 {
                    print("下载A=\(Thread.current),i=\(i)")
                }
            }
        }
        queue.async(group: group, qos: .default, flags: []) {
            for i in 0...5 {
                print("下载B=\(Thread.current),i=\(i)")
            }
        }
        
        group.notify(queue: queue) {
            print("回到该队列中执行=\(Thread.current)")
        }
        print("test16 finish")
    }
    
    func test15() -> Void {
        print("test15 start")
        let group = DispatchGroup()
        let queue = DispatchQueue.global()
        queue.async(group: group, qos: .default, flags: []) {
            for i in 0...5 {
                print("下载A=\(Thread.current),i=\(i)")
            }
        }
        queue.async(group: group, qos: .default, flags: []) {
            for i in 0...5 {
                print("下载B=\(Thread.current),i=\(i)")
                sleep(1)
            }
        }
        let result = group.wait(timeout: .now() + 3)
        switch result {
        case .success:
            print("\(Thread.current) 不超时, 上面的两个任务都执行完")
        case .timedOut:
            print("\(Thread.current) 超时了, 上面的任务还没执行完执行这了")
        }
        group.notify(queue: queue) {
            print("回到该队列中执行=\(Thread.current)")
        }
        print("test15 finish")
    }
    
    func test14() -> Void {
        print("test14 start")
        let group = DispatchGroup()
        let queue = DispatchQueue.global()
        queue.async(group: group, qos: .default, flags: []) {
            for i in 0...5 {
                print("下载A=\(Thread.current),i=\(i)")
            }
        }
        queue.async(group: group, qos: .default, flags: []) {
            for i in 0...5 {
                print("下载B=\(Thread.current),i=\(i)")
            }
        }
        queue.async(group: group, qos: .default, flags: []) {
            print("下载C=\(Thread.current)")
        }
        
        group.notify(queue: queue) {
            print("回到该队列中执行=\(Thread.current)")
        }
        print("test14 finish")
    }
    
    // 延迟队列
    func test13() -> Void {
        print("test13 start")
        DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 2) {
            print("test13=\(Thread.current)")
        }
        print("test13 finish")
    }
    
    func test12() -> Void {
        print("test12 start")
        DispatchQueue.global().async {
            print("test12 1=\(Thread.current)")
            let url = URL(string: "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png")
            guard let data = try? Data(contentsOf: url!) else {
                return
            }
            DispatchQueue.main.async {
                print("test12 2=\(Thread.current)")
                let img = UIImageView(frame: CGRect(x: 100, y: 200, width: 200, height: 200))
                img.contentMode = .scaleAspectFit
                self.view.addSubview(img)
                img.image = UIImage(data: data)
            }
        }
        print("test12 finish")
    }
    
    func test11() -> Void {
        print("test11 start")
        let queue = DispatchQueue(label: "test11", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: .none)
        queue.sync {
            print("登录，test11=\(Thread.current)")
        }
        queue.async {
            print("下载A，test11=\(Thread.current)")
        }
        queue.async {
            print("下载B，test11=\(Thread.current)")
        }
        print("test11 finish")
    }
    
    func test10() -> Void {
        print("test10 start")
        DispatchQueue.global().async {
            print("test10=\(Thread.current)")
        }
        print("test10 finish")
    }
    
    func test9() -> Void {
        print("test9 start")
        DispatchQueue.global().sync {
            print("test9=\(Thread.current)")
        }
        print("test9 finish")
    }
    
    // crash
    func test8() -> Void {
        print("test8 start")
        DispatchQueue.main.sync {
            print("test8=\(Thread.current)")
        }
        print("test8 finish")
    }
    
    func test7() -> Void {
        print("test7 start")
        DispatchQueue.main.async {
            print("test7=\(Thread.current)")
        }
        print("test7 finish")
    }
    
    func test6() -> Void {
        print("test6 start")
        // 并行队列
        DispatchQueue(label: "test6", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil).async {
            print("test6=\(Thread.current)")
        }
        print("test6 finish")
    }
    
    func test5() -> Void {
        print("test5 start")
        // 并行队列
        DispatchQueue(label: "test5", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: .main).async {
            print("test5=\(Thread.current)")
        }
        print("test5 finish")
    }
    
    func test4() -> Void {
        print("test4 start")
        // 并行队列
        DispatchQueue(label: "test4", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: .none).async {
            print("test4=\(Thread.current)")
        }
        print("test4 finish")
    }
    
    func test3() -> Void {
        print("test3 start")
        // 并行队列
        DispatchQueue(label: "test3", qos: .default, attributes: .concurrent, autoreleaseFrequency: .inherit, target: .none).sync {
            print("test3=\(Thread.current)")
        }
        print("test3 finish")
    }
    
    func test2() -> Void {
        print("test2 start")
        // 串行队列
        DispatchQueue(label: "test2").sync {
            print("test2=\(Thread.current)")
        }
        print("test2 finish")
    }
    
    func test1() -> Void {
        print("test1 start")
        // 串行队列
        DispatchQueue(label: "thread1").async {
            print("test1=\(Thread.current)")
        }
        print("test1 finish")
    }
}
